package shortcircuit.graphics;

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.awt.image.RescaleOp;
import java.io.File;

import javax.swing.*;

import shortcircuit.Display;
import shortcircuit.GameEngine;
import shortcircuit.engine.EndlessEngine;
import shortcircuit.engine.InstructionsEngine;
import shortcircuit.engine.MainMenu;

/**
 * This class holds the graphics and user interface component of MainMenu, in an easy
 * to store extension of a JPanel. This panel is added and retrieved in Display whenever
 * the main menu function is accessed in the game through user input. It also holds a
 * thread for the mouse input, which looks at user mouse input and translates it into
 * the user preference for the type of gaming style, signaling Display to change the
 * screens accordingly.
 * 
 * @author David Li
 */
public class MainMenuScreen extends JPanel{
	private ImageIcon[] wallClips;
	private JButton[] buttonSet;
	public static ImageIcon currentWallClip;
	public static VideoAnimation demoClipRunner;
	private int demoClipCount;
	private JLabel videoLabel;
	private final int VIDEO_SIZE = 5;
	public static JPanel bgPanel;
	private JLabel bgLabel;
	public MainMenu mainEngine;
	private double animationCount;
	private Animator theAnimator;
	private Image offImage;
	private Graphics offGraphics;
	private Image bgImage;
	
	public MainMenuScreen(MainMenu mainEngine)
	{
		this.mainEngine = mainEngine;
		addMouseListener(new MouseInput());
		theAnimator = new Animator();
		theAnimator.start();
	}

	public void add(JButton[] theButtons){

		buttonSet = theButtons;

		videoLabel = new JLabel();
		demoClipRunner = new VideoAnimation();
		demoClipRunner.start();
		int screenLength = 0;

		setLayout(null);

		
		//JPanel demoPanel = demoVideo.gameScreen;
		//demoPanel.setLocation(400,0);
		//add(demoPanel);
		

		bgPanel = new JPanel();
		bgLabel = new JLabel();
		bgLabel.setSize(440, 420);
		bgLabel.setLocation(0, 0);
		bgPanel.setSize(1000, 500);
		bgPanel.setLocation(0, -10);
		bgPanel.setLayout(null);
		loadWallClip(VIDEO_SIZE);
		
		for(int index=0;index<2;index++){
			buttonSet[index].setLocation(240, 70 + 60 * index);
			buttonSet[index].setSize(160, 30);
			add(buttonSet[index]);
		}

		loadNextImage();

		videoLabel.setSize(450,450);
		videoLabel.setLocation(400, 0);
		add(videoLabel);
		bgPanel.add(bgLabel);
		add(bgPanel);

		setSize(440, 420);
	}

	
	public ImageIcon getCurrentWallClip()
	{
		return wallClips[demoClipCount % VIDEO_SIZE];
	}

	public void loadWallClip(int videoSize)
	{
		wallClips = new ImageIcon[videoSize];
		MediaTracker mt = new MediaTracker(this);
		Toolkit tk = this.getToolkit();
		for(int i = 0; i < videoSize; i++)
		{
			Image theImage = tk.getImage("resources/wall" + i + ".jpg");
			wallClips[i] = new ImageIcon(theImage);
			mt.addImage(theImage, i);
		}
		bgImage = tk.getImage("resources/bg.png").getScaledInstance(1000, 500, Image.SCALE_SMOOTH);
		bgLabel.setIcon(new ImageIcon(bgImage));

		mt.addImage(bgImage, videoSize);
		try
		{
			mt.waitForAll();
		}
		catch(InterruptedException e) {}
	}

	private void loadNextImage()
	{
		try
		{
			demoClipCount += 1;
			currentWallClip = wallClips[demoClipCount % VIDEO_SIZE];
			videoLabel.setIcon(currentWallClip);
		}
		catch(NullPointerException e) {}
	}

	public void paint(Graphics g)
	{
        if(offGraphics == null || getWidth() != offImage.getWidth(null) || getHeight() != offImage.getHeight(null))
        {
			offImage = createImage(getWidth(), getHeight());
			offGraphics = offImage.getGraphics();
        }
		
		
		//initialize variables
		double imageTransparency = 0.0;
		int titleImageX = 15;
		int titleImageY = 185;
		int modesX = 440;
		int demoImageY = 420;
		double instructionsTransparency = 0.0;
		int titleImageWidth = 400;
		int titleImageHeight = 50;
		double[] stepPoints = {100.0, 200.0, 210.0, 250.0, 300.0, 350.0};
		
		//make adjustments
		if(animationCount > 0 && animationCount < stepPoints[0])
		{
			animationCount = stepPoints[0];
		}
		if(animationCount > stepPoints[0] && animationCount <= stepPoints[1])
		{
			imageTransparency = (animationCount - stepPoints[0]) / (stepPoints[1] - stepPoints[0]);
		}
		if(animationCount > stepPoints[1] && animationCount <= stepPoints[2])
		{
			imageTransparency = 1.0f;
			titleImageY = titleImageY - (int) ((animationCount - stepPoints[1]) / (stepPoints[3] - stepPoints[1]) * 180.0);
		}
		if(animationCount > stepPoints[2] && animationCount <= stepPoints[3])
		{
			modesX = modesX - (int) ((animationCount - stepPoints[2]) / (stepPoints[3] - stepPoints[2]) * 200.0);
			titleImageY = titleImageY - (int) ((animationCount - stepPoints[1]) / (stepPoints[3] - stepPoints[1]) * 180.0);			
			imageTransparency = 1.0f;
		}
		if(animationCount > stepPoints[3] && animationCount < stepPoints[4])
		{
			modesX = 240;
			imageTransparency = 1.0f;
			titleImageY = 5;
			demoImageY = demoImageY - (int) ((animationCount - stepPoints[3]) / (stepPoints[4] - stepPoints[3]) * 370.0);
		}
		if(animationCount > stepPoints[4] && animationCount < stepPoints[5])
		{
			modesX = 240;
			imageTransparency = 1.0f;
			titleImageY = 5;
			demoImageY = 70;
			instructionsTransparency = (animationCount - stepPoints[0]) / (stepPoints[1] - stepPoints[0]);
		}
		if(animationCount > stepPoints[5])
		{
			modesX = 240;
			imageTransparency = 1.0f;
			titleImageY = 5;
			demoImageY = 70;
			instructionsTransparency = 1.0f;
		}
		
		//set variables
		float[] scales = {1, 1, 1, (float) imageTransparency};
		float[] offsets = new float[4];
		RescaleOp titleImageROP = new RescaleOp(scales, offsets, null);
		
		//draw images
		Graphics2D g2D = (Graphics2D) offGraphics;
		offGraphics.clearRect(0, 0, 1000, 1000);
		g2D.drawImage(bgImage, 0, 0, this);
		for(int i = 0; i < 2; i++)
		{
			g2D.drawImage(Display.modeImages[i], modesX, 70 + 60 * i, this);
		}
		g2D.setColor(Color.GRAY);
		g2D.drawImage(Display.demoImage, 20, demoImageY, 180, 300, this);
		g2D.drawImage(Display.howToPlayImage, 20, 380, 90, 20, this);
		BufferedImage bi = new BufferedImage(titleImageWidth, titleImageHeight, BufferedImage.TYPE_INT_ARGB);
		bi.getGraphics().drawImage(Display.titleImage, 0, 0, null);
		if(Display.titleImage != null)
			g2D.drawImage(bi, titleImageROP, titleImageX, titleImageY);
		
		g.drawImage(offImage, 0, 0, this);
	}

	
	private class Animator extends Thread
	{
		public void run()
		{
			while(Thread.currentThread() == theAnimator)
			{
				try
				{
					Thread.sleep(10);
				}
				catch(InterruptedException e) {}
				animationCount++;
				repaint();
			}
		}
	}
	
	private class VideoAnimation extends Thread
	{
		public void run()
		{
			while(Thread.currentThread() == demoClipRunner)
			{
				try
				{
					Thread.sleep(90);
				}
				catch(InterruptedException e)
				{
					break;
				}
				loadNextImage();
			}
		}
	}
	
	private class MouseInput extends MouseAdapter
	{
		public void mousePressed(MouseEvent e)
		{
			if(e.getPoint().x >= 20 && e.getPoint().y >= 380 &&
					e.getPoint().x <= 110 && e.getPoint().y <= 400)
			{
				mainEngine._Display.clearScreens();
				new InstructionsEngine(mainEngine._Display);
				
			}
		}
	}
}
